<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
<!-- designer-manual.qdoc -->
  <title>创建自定义小部件(Widget)扩展 | Qt Designer 手册</title>
  <link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
  <script type="text/javascript">
    document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
    // loading style sheet breaks anchors that were jumped to before
    // so force jumping to anchor again
    setTimeout(function() {
        var anchor = location.hash;
        // need to jump to different anchor first (e.g. none)
        location.hash = "#";
        setTimeout(function() {
            location.hash = anchor;
        }, 0);
    }, 0);
  </script>
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="main">
    <div class="main-rounded">
      <div class="navigationbar">
        <table><tr>
<td ><a href="../qtdoc/index.html">Qt 5.14</a></td><td ><a href="qtdesigner-manual.html">Qt Designer 手册</a></td><td >创建自定义小部件(Widget)扩展</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right"><a href="qtdesigner-manual.html">Qt 5.14.2 参考文档</a></td>
        </tr></table>
      </div>
    </div>
<div class="content">
<div class="line">
<div class="content mainContent">
  <link rel="prev" href="designer-creating-custom-widgets.html" />
  <link rel="next" href="designer-ui-file-format.html" />
<p class="naviNextPrevious headerNavi">
<a class="prevPage" href="designer-creating-custom-widgets.html">创建自定义小部件（Widgets）</a>
<span class="naviSeparator">  &#9702;  </span>
<a class="nextPage" href="designer-ui-file-format.html">UI文件格式</a>
</p><p/>
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#extension-types">扩展类型</a></li>
<li class="level1"><a href="#creating-an-extension">创建扩展</a></li>
<li class="level1"><a href="#exposing-an-extension-to-qt-designer">将扩展暴露给Qt Designer</a></li>
<li class="level2"><a href="#creating-an-extension-factory">创建扩展工厂</a></li>
<li class="level2"><a href="#accessing-qt-designer-s-extension-manager">访问 Qt Designer 的扩展管理器</a></li>
<li class="level1"><a href="#related-examples">相关的例子</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">创建自定义小部件(Widget)扩展</h1>
<span class="subtitle"></span>
<!-- $$$designer-creating-custom-widgets-extensions.html-description -->
<div class="descr"> <a name="details"></a>
<p>有了 <i>Qt Designer</i> 的自定义小部件插件后，可以使用自定义小部件扩展在 <i>Qt Designer</i> 的工作空间中为其提供预期的行为和功能 。</p>
<a name="extension-types"></a>
<h2 id="extension-types">扩展类型</h2>
<p><i>Qt Designer</i> 中有几种可用的扩展类型 。您可以在相同的模式中使用所有这些扩展，只替换各自的扩展基类 。</p>
<p>在实现自定义多页面容器时， <a href="qdesignercontainerextension.html">QDesignerContainerExtension</a> 是必要的 。</p>
<div class="table"><table class="generic">
 <tr valign="top" class="odd"><td ><img src="images/designer-manual-taskmenuextension.png" alt="" /></td><td ><b><a href="qdesignertaskmenuextension.html">QDesignerTaskMenuExtension</a></b><p><a href="qdesignertaskmenuextension.html">QDesignerTaskMenuExtension</a> 对于定制小部件很有用 。它提供了一个扩展，允许您将自定义菜单项添加到 <i>Qt Designer</i> 的任务菜单中 。</p>
<p><a href="qtdesigner-taskmenuextension-example.html">任务菜单扩展</a> 示例演示了如何使用这个类 。</p>
</td></tr>
<tr valign="top" class="even"><td ><img src="images/designer-manual-containerextension.png" alt="" /></td><td ><b><a href="qdesignercontainerextension.html">QDesignerContainerExtension</a></b><p>在实现自定义多页面容器时，<a href="qdesignercontainerextension.html">QDesignerContainerExtension</a> 是必要的。它提供了一个扩展，允许您为 <i>Qt Designer</i> 中的多页面容器插件添加和删除页面 。</p>
<p><a href="qtdesigner-containerextension-example.html">容器扩展</a> 示例进一步解释了如何使用这个类 。</p>
<p><b>注意: </b> 由于某些小部件 (例如 <a href="../qtwidgets/qtabwidget.html">QTabWidget</a>) 的实现方式，不可能为它们添加定制的每页属性 。</p></td></tr>
</table></div>
<div class="table"><table class="generic">
 <tr valign="top" class="odd"><td ><img src="images/designer-manual-membersheetextension.png" alt="" /></td><td ><b><a href="qdesignermembersheetextension.html">QDesignerMemberSheetExtension</a></b><p><a href="qdesignermembersheetextension.html">QDesignerMemberSheetExtension</a> 类允许您操作在连接信号和槽时显示的小部件的成员函数 。</p>
</td></tr>
<tr valign="top" class="even"><td ><img src="images/designer-manual-propertysheetextension.png" alt="" /></td><td ><b><a href="qdesignerpropertysheetextension.html">QDesignerPropertySheetExtension</a>, <a href="qdesignerdynamicpropertysheetextension.html">QDesignerDynamicPropertySheetExtension</a></b><p>这些扩展类允许您控制小部件的属性如何在 <i>Qt Designer</i> 的属性编辑器中显示 。</p>
</td></tr>
</table></div>
<p><i>Qt Designer</i> 使用 <a href="qdesignerpropertysheetextension.html">QDesignerPropertySheetExtension</a> 和 the <a
  href="qdesignermembersheetextension.html">QDesignerMemberSheetExtension</a> 类来提供它的属性、信号和槽编辑器 。只要在工作区中选择了一个小部件，<i>Qt Designer</i> 就会查询小部件的属性表扩展;同样，每当请求两个小部件之间的连接时，<i>Qt Designer</i> 将查询小部件的成员表扩展 。</p>
<p><b>警告:</b> 所有小部件都有默认属性和成员表 。如果实现自定义属性表或成员表扩展，则自定义扩展将覆盖默认表 。</p>
<a name="creating-an-extension"></a>
<h2 id="creating-an-extension">创建扩展</h2>
<p>要创建扩展，您必须同时继承 <a href="../qtcore/qobject.html">QObject</a> 和适当的基类，并重新实现其功能。由于我们正在实现一个接口，我们必须确保使用扩展类定义中的 <a href="../qtcore/qobject.html#Q_INTERFACES">Q_INTERFACES</a>() 宏让元对象系统知道它 。例如:</p>
<pre class="cpp">

  <span class="keyword">class</span> MyExtension: <span class="keyword">public</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span><span class="operator">,</span>
                     <span class="keyword">public</span> QdesignerContainerExtension
  {
      Q_OBJECT
      Q_INTERFACE(<span class="type"><a href="qdesignercontainerextension.html">QDesignerContainerExtension</a></span>)

      <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
  }

</pre>
<p>这使 <i>Qt Designer</i> 能够使用 <a href="../qtcore/qobject.html#qobject_cast">qobject_cast</a>() 函数仅使用 <a href="../qtcore/qobject.html">QObject</a> 指针查询受支持的接口 。</p>
<a name="exposing-an-extension-to-qt-designer"></a>
<h2 id="exposing-an-extension-to-qt-designer">将扩展暴露给 Qt Designer</h2>
<p>在 <i>Qt Designer</i> 中，只有在需要扩展时才会创建它们。因此，在实现扩展时，您必须子类化 <a href="qextensionfactory.html">QExtensionFactory</a> ，以创建一个能够生成扩展实例的类。此外，您必须在 <i>Qt Designer</i> 的扩展管理器中注册您的工厂;扩展管理器处理扩展的构造。</p>
<p>当一个扩展被请求时，<i>Qt Designer</i> 的扩展管理器将运行其注册的工厂，为每个工厂调用 <a href="qextensionfactory.html#createExtension">QExtensionFactory::createExtension</a>() ，直到找到一个能够为所选小部件创建所请求的扩展的工厂。然后，该工厂将创建该扩展的一个实例。</p>
<p class="centerAlign"><img src="images/qtdesignerextensions.png" alt="" /></p><a name="creating-an-extension-factory"></a>
<h3 id="creating-an-extension-factory">创建扩展工厂</h3>
<p><a href="qextensionfactory.html">QExtensionFactory</a> 类提供了一个标准的扩展工厂，但是它也可以用作自定义扩展工厂的接口 。</p>
<p>其目的是重新实现 <a href="qextensionfactory.html#createExtension">QExtensionFactory::createExtension</a>() 函数，使其能够创建您的扩展，比如 <a href="qtdesigner-containerextension-example.html">MultiPageWidget</a> 容器扩展 。</p>
<p>您可以创建一个新的 <a href="qextensionfactory.html">QExtensionFactory</a> 并重新实现 <a href="qextensionfactory.html#createExtension">QExtensionFactory::createExtension</a>() 函数:</p>
<pre class="cpp">

  <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>ANewExtensionFactory<span class="operator">::</span>createExtension(<span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>object<span class="operator">,</span>
          <span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>iid<span class="operator">,</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>parent) <span class="keyword">const</span>
  {
      <span class="keyword">if</span> (iid <span class="operator">!</span><span class="operator">=</span> Q_TYPEID(<span class="type"><a href="qdesignercontainerextension.html">QDesignerContainerExtension</a></span>))
          <span class="keyword">return</span> <span class="number">0</span>;

      <span class="keyword">if</span> (MyCustomWidget <span class="operator">*</span>widget <span class="operator">=</span> qobject_cast<span class="operator">&lt;</span>MyCustomWidget<span class="operator">*</span><span class="operator">&gt;</span>
              (object))
          <span class="keyword">return</span> <span class="keyword">new</span> MyContainerExtension(widget<span class="operator">,</span> parent);

      <span class="keyword">return</span> <span class="number">0</span>;
  }

</pre>
<p>或者你也可以使用现有的工厂，扩展 <a href="qextensionfactory.html#createExtension">QExtensionFactory::createExtension</a>() 函数，让工厂也可以创建你的自定义扩展:</p>
<pre class="cpp">

  <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>AGeneralExtensionFactory<span class="operator">::</span>createExtension(<span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>object<span class="operator">,</span>
          <span class="keyword">const</span> <span class="type"><a href="../qtcore/qstring.html">QString</a></span> <span class="operator">&amp;</span>iid<span class="operator">,</span> <span class="type"><a href="../qtcore/qobject.html">QObject</a></span> <span class="operator">*</span>parent) <span class="keyword">const</span>
  {
      MyCustomWidget <span class="operator">*</span>widget <span class="operator">=</span> qobject_cast<span class="operator">&lt;</span>MyCustomWidget<span class="operator">*</span><span class="operator">&gt;</span>(object);

      <span class="keyword">if</span> (widget <span class="operator">&amp;</span><span class="operator">&amp;</span> (iid <span class="operator">=</span><span class="operator">=</span> Q_TYPEID(<span class="type"><a href="qdesignertaskmenuextension.html">QDesignerTaskMenuExtension</a></span>))) {
           <span class="keyword">return</span> <span class="keyword">new</span> MyTaskMenuExtension(widget<span class="operator">,</span> parent);

      } <span class="keyword">else</span> <span class="keyword">if</span> (widget <span class="operator">&amp;</span><span class="operator">&amp;</span> (iid <span class="operator">=</span><span class="operator">=</span> Q_TYPEID(<span class="type"><a href="qdesignercontainerextension.html">QDesignerContainerExtension</a></span>))) {
          <span class="keyword">return</span> <span class="keyword">new</span> MyContainerExtension(widget<span class="operator">,</span> parent);

      } <span class="keyword">else</span> {
          <span class="keyword">return</span> <span class="number">0</span>;
      }
  }

</pre>
<a name="accessing-qt-designer-s-extension-manager"></a>
<h3 id="accessing-qt-designer-s-extension-manager">访问 Qt Designer 的扩展管理器</h3>
<p>在实现自定义小部件插件时，您必须子类化QDesignerCustomWidgetInterface，以将您的插件公开给Qt Designer。在为Qt设计器创建自定义小部件一节中详细介绍了这一点。扩展工厂的注册通常是在QDesignerCustomWidgetInterface::initialize()函数中完成的:</p>
<pre class="cpp">

  <span class="type">void</span> MyPlugin<span class="operator">::</span>initialize(<span class="type"><a href="qdesignerformeditorinterface.html">QDesignerFormEditorInterface</a></span> <span class="operator">*</span>formEditor)
  {
      <span class="keyword">if</span> (initialized)
          <span class="keyword">return</span>;

      <span class="type"><a href="qextensionmanager.html">QExtensionManager</a></span> <span class="operator">*</span>manager <span class="operator">=</span> formEditor<span class="operator">-</span><span class="operator">&gt;</span>extensionManager();
      Q_ASSERT(manager <span class="operator">!</span><span class="operator">=</span> <span class="number">0</span>);

      manager<span class="operator">-</span><span class="operator">&gt;</span>registerExtensions(<span class="keyword">new</span> MyExtensionFactory(manager)<span class="operator">,</span>
                                  Q_TYPEID(<span class="type"><a href="qdesignertaskmenuextension.html">QDesignerTaskMenuExtension</a></span>));

      initialized <span class="operator">=</span> <span class="keyword">true</span>;
  }

</pre>
<p>在 <a href="qdesignercustomwidgetinterface.html#initialize">QDesignerCustomWidgetInterface::initialize</a>() 函数中的 <code>formEditor</code> 参数是一个指向 <i>Qt Designer</i> 当前 <a href="qdesignerformeditorinterface.html">QDesignerFormEditorInterface</a> 对象的指针。您必须使用 <a href="qdesignerformeditorinterface.html#extensionManager">QDesignerFormEditorInterface::extensionManager</a>() 函数来检索到 <i>Qt Designer</i> 的扩展管理器的接口。然后使用 <a href="qextensionmanager.html#registerExtensions">QExtensionManager::registerExtensions</a>() 函数注册您的自定义扩展工厂。</p>
<a name="related-examples"></a>
<h2 id="related-examples">相关的例子</h2>
<p>有关在 <i>Qt Designer</i> 中创建自定义小部件扩展的详细信息，请参阅 <a href="qtdesigner-taskmenuextension-example.html">任务菜单扩展</a> 和 <a
  href="qtdesigner-containerextension-example.html">容器扩展</a> 示例。</p>
</div>
<!-- @@@designer-creating-custom-widgets-extensions.html -->
<p class="naviNextPrevious footerNavi">
<a class="prevPage" href="designer-creating-custom-widgets.html">创建自定义小部件（Widgets）</a>
<span class="naviSeparator">  &#9702;  </span>
<a class="nextPage" href="designer-ui-file-format.html">UI文件格式</a>
</p>
        </div>
       </div>
   </div>
   </div>
</div>
<div class="footer">
   <p>
   <acronym title="Copyright">&copy;</acronym> 2020 The Qt Company Ltd.
   Documentation contributions included herein are the copyrights of
   their respective owners.<br/>    The documentation provided herein is licensed under the terms of the    <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation    License version 1.3</a> as published by the Free Software Foundation.<br/>    Qt and respective logos are trademarks of The Qt Company Ltd.     in Finland and/or other countries worldwide. All other trademarks are property
   of their respective owners. </p>
</div>
</body>
</html>
